package ar.com.photo_admin.service.security

import ar.com.photo_admin.domain.User;
import ar.com.photo_admin.domain.user.PhotoAdminUserDetails

import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUserDetailsService
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.authority.GrantedAuthorityImpl
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

class PhotoAdminUserDetailsService implements GrailsUserDetailsService {

	static final List NO_ROLES = [new GrantedAuthorityImpl('ROLE_USER')]
	
	UserDetails loadUserByUsername(String username, boolean loadRoles) throws UsernameNotFoundException, DataAccessException {
		return loadUserByUsername(username)
	}
	
	UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException, DataAccessException {
		
		User.withTransaction {
			User user = username?.contains("@") ? User.findByEmail(username) : User.findByUsername(username)
					
			if (!user) throw new UsernameNotFoundException(
				'User not found by username', username)
			
			return makeUserDetails(user)
		}
	}
	
	UserDetails loadUserByFacebookUid(String facebookUid) {
		
		User.withTransaction {
			User user = User.findByFacebookUid(facebookUid)
			if (!user) throw new UsernameNotFoundException(
					  'User not found by FacebookUid', facebookUid)
	
			return makeUserDetails(user)	 
		}
	}
			
	private PhotoAdminUserDetails makeUserDetails(User user) {
		
		def authorities = user.authorities.collect {
			new GrantedAuthorityImpl(it.authority)
		}
		
		PhotoAdminUserDetails userDetails = new PhotoAdminUserDetails(
			user.username,
			user.password,
			user.enabled,
			!user.accountExpired,
			!user.passwordExpired,
			!user.accountLocked,
			authorities ?: NO_ROLES,
			user.id,
			user.email,
			user.facebookUid)
		
		return userDetails
	  }
}
